package nf;

import java.util.ArrayList;
import java.util.concurrent.BlockingDeque;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.LinkedBlockingDeque;
import java.util.concurrent.atomic.AtomicInteger;

import nf.modular.data.ClassificationResult;
import nf.modular.data.QueueEntry;
import nf.pluginsys.Wiring;

class ClassificationWorker implements Runnable 
{
	private ArrayList<QueueEntry> fileQueue = new ArrayList<QueueEntry>();
	volatile boolean abort = false;
	volatile boolean done = false;
	private Wiring wiring = null;
	
	public ClassificationWorker(ArrayList<QueueEntry> fileQueue, Wiring wiring)
	{
		this.fileQueue = fileQueue;
		this.wiring = wiring;
	}

	@Override
	public void run() {
		//int count = 0;
		
		System.out.println("THREAD ClassificationWorker START");
		
		ArrayList<QueueEntry> filteredQueue = new ArrayList<QueueEntry>();
		
		for(QueueEntry f : fileQueue)
		{
			if(!f.processed)
				filteredQueue.add(f);
		}
		
		//int max = filteredQueue.size();
		
		//////////////////////////////////
		
		BlockingDeque<QueueEntry> fileQueue = new LinkedBlockingDeque<QueueEntry>();
		ConcurrentHashMap<String, ClassificationResult> results = new ConcurrentHashMap<String, ClassificationResult>();
		
		int cores = (SettingsStore.coreUsage == 0) ? Runtime.getRuntime().availableProcessors() : SettingsStore.coreUsage;
		
		//for(File file : files)
		for(QueueEntry file : filteredQueue)
			fileQueue.add(file);
		
		int fileCount = fileQueue.size();
		AtomicInteger atomCounter = new AtomicInteger();
		AtomicInteger killCount = new AtomicInteger();
		
		ClassificationThread[] workers = new ClassificationThread[cores];
		for(int i = 0; i < cores; ++i)
			workers[i] = new ClassificationThread(fileQueue, results, atomCounter, atomCounter, wiring, i);
		
		for(int i = 0; i < cores; ++i)
		{
			//System.out.println("THREAD " + (i+1) + " OF " + cores);
			Thread t = new Thread(workers[i]);
			t.start();
			try {
				Thread.sleep(10);
			} catch (InterruptedException e) {}
		}
		
		int lastCount = 0;
		
		while(atomCounter.get() < fileCount && killCount.get() < cores)
		{
			try {
				Thread.sleep(100);
			} catch (InterruptedException e) {}
			int ccount = atomCounter.get();
			if(ccount > lastCount)
			{
				//System.out.println("PROGRESS : " + ccount + " / " + fileCount);
				MainWindow.instance.progress = (int)((float)ccount / (float)fileCount * 100.0f);
				MainWindow.instance.asyncUpdate();
			}
			lastCount = ccount;
			
			if(abort)
			{
				fileQueue.clear();
				//break;
			}
		}
		
		//System.out.println("All entries processed.");
		
		done = true;
		MainWindow.instance.progress = abort ? 0 : 100;
		MainWindow.instance.asyncUpdate();
		
		try {
			Thread.sleep(100);
		} catch (InterruptedException e) {}
		System.gc();
		
		System.out.println("THREAD ClassificationWorker END");
	}
}
